from typing import Tuple

from lucommon.logger import lu_logger

import agent
import conf
from async_task.services import register_job, AsyncTask
from utils import concurrence_requests
from . import check_agent_status, check_concurrence_result


class AsyncTaskDeployBashCompletion(AsyncTask):
    def task_impl(self, nodes, pkg, application_dir) -> Tuple[int, any]:
        bash_completion_request_infos = {}
        for ip in nodes:
            bash_completion_request_infos[str(ip)] = {
                "url": "http://{}:{}{}".format(ip, agent.AGENT_PORT, agent.INSTALL_BASH_COMPLETION),
                "method": "POST",
                "json": {
                    "pkg_url": {"url": pkg.url, "extract_type": pkg.extract_type, "save_path": ""},
                    "application_dir": application_dir,
                }
            }
        lu_logger.debug("bash_completion_request_infos:{}".format(bash_completion_request_infos))
        bash_completion_result = concurrence_requests(bash_completion_request_infos)
        if check_concurrence_result(bash_completion_result):
            return 0, bash_completion_result
        return -1, bash_completion_result


def job_deploy_bash_completion(params):
    nodes = params["nodes"]
    application_dir = params["application_dir"]
    version = params["version"]

    pkg = conf.BASH_COMPLETION_PACKAGE.get(version)
    if not pkg:
        return -1, "无适用的bash_completion,valid_version:{}".format(",".join(list(conf.NGINX_PACKAGE.keys()))), {}

    # 检查agent状态
    err_ips = check_agent_status(nodes)
    if err_ips:
        return -1, "节点检查失败,{}".format(",".join(err_ips)), {}

    job = register_job(
        "部署bash_completion",
        [
            [
                AsyncTaskDeployBashCompletion(
                    "部署bash_completion",
                    {
                        "nodes": nodes,
                        "pkg": pkg,
                        "application_dir": application_dir,
                    }
                ),
            ],
        ]
    )
    data = {
        "job_id": job.id,
    }

    return 0, "", data
